﻿/* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
 
Copyright (C) 2010 by Tomasz Pluskiewicz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */

using System.Collections;
using System.Collections.Specialized;
using Castle.Components.Binder;
using Castle.MonoRail.Framework;
using Castle.MonoRail.Framework.Helpers;
using Yama.MVC.MonoRail.Extensions;
using Yama.MVC.MonoRail.Filters;

namespace Yama.MVC.MonoRail.Controllers
{
    /// <summary>
    /// Controller exposing basic AJAX functionality
    /// </summary>
    [Filter(ExecuteWhen.Always, typeof(AjaxFilter))]
    public abstract class AjaxEnabledController : SmartDispatcherController
    {
        protected AjaxEnabledController(){}

        protected AjaxEnabledController(IDataBinder binder):base(binder){}

        /// <summary>
        /// Checks wheather request is ajax. Default based on http header X-Requested-With
        /// </summary>
        protected bool RequestIsAjax
        {
            get { return AjaxContextAdapter.IsAjax; }
        }

        /// <summary>
        /// Renders a JS generator file (brailjs) for the current action
        /// </summary>
        protected internal void RenderJSGenerator()
        {
            RenderJSGenerator(ControllerContext.Action);
        }

        /// <summary>
        /// Renders a JS generator file (brailjs) for the selected action. 
        /// Rendered will be file named as according to AjaxEnabledController#JsGeneratorFormat.
        /// Ths file must exist in the current controller's view folder
        /// </summary>
        protected internal void RenderJSGenerator(string action)
        {
            RenderView(string.Format(AjaxFilter.JSGeneratorViewFormat, "", this.Name, action));
        }

        /// <summary>
        /// If request is ajax, performs a client-side javascript redirect to the given action.
        /// Otherwise preforms a standard redirect
        /// </summary>
        /// <param name="area">controller's area</param>
        /// <param name="controller">controller name</param>
        /// <param name="action">action name</param>
        /// <param name="parameters">redirect querystrings</param>
        protected internal void AjaxRedirect(string area, string controller, string action, NameValueCollection parameters)
        {
            if (RequestIsAjax)
            {
                UrlHelper urlHelper = (UrlHelper)Helpers["Url"];

                IDictionary querystring = new DictHelper.MonoRailDictionary();
                if (parameters != null)
                    querystring = new DictHelper().FromNameValueCollection(parameters);
                var urlParams = new DictHelper.MonoRailDictionary
                                    {
                                        {"querystring", querystring},
                                        {"Area", area},
                                        {"Controller", controller},
                                        {"Action", action}
                                    };

                Flash["RedirUrl"] = urlHelper.For(urlParams);

                RedirectToAction("AjaxRedirect");
            }
            else
            {
                Redirect(area, controller, action, parameters);
            }
        }

        /// <summary>
        /// If current request is AJAX, redirects using location.href. 
        /// Otherwise performs standard rediterct
        /// </summary>
        protected internal void AjaxRedirectToUrl(string url)
        {
            if (RequestIsAjax)
            {
                Flash["RedirUrl"] = url;

                RedirectToAction("AjaxRedirect");
            }
            else
            {
                RedirectToUrl(url);
            }
        }

        [SkipFilter]
        public void AjaxRedirect()
        {
            RenderView("Ajax", "Redirect", true, "text/javascript; charset=utf-8");

            AjaxContextAdapter.IsAjaxRedirect = true;
        }

        public void AjaxError()
        {
            if (Context.Request.UrlReferrer == null)
            {
                RedirectToSiteRoot();
            }
            else
            {
                RenderText("alert('dupa')");
            }
        }
    }
}